package com.btm.distrb.config;

import com.btm.distrb.model.AllDB;
import com.btm.distrb.model.DBInfo;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Map;

public class ReadConfigFile {

    private static final String endStr = "\r\n";
    private Map<String,String> configMap = new HashMap<>();
    private static AllDB allDB = new AllDB();

    public void getConfig(Class clazz,String configName) throws FileNotFoundException,IOException{
        String stdPath = clazz.getResource("").getPath();
        if (null != stdPath){
            if (stdPath.startsWith("file:/")){
                stdPath = stdPath.substring(6);
            }
            int index = stdPath.indexOf("!");
            if (0<index) {
                stdPath = stdPath.substring(0, index);
            }
            index = stdPath.lastIndexOf("/");
            if (0<index){
                stdPath = stdPath.substring(0,index);
            }
            stdPath += "/"+configName;
            System.out.println("Config path is ["+stdPath+"]");
            //读取配置文件
            readConfig(stdPath);
            //转译配置文件
            setAllDB();
        }else {
            throw new FileNotFoundException("no get file path.");
        }
    }

    /**
     * 读取配置文件
     * @param path
     * @throws FileNotFoundException
     */
    private void readConfig(String path) throws IOException{
        FileInputStream fin = new FileInputStream(new File(path));
        FileChannel fchannel = fin.getChannel();
        int capacity = 1024;//设置缓冲区容量，单位字节
        ByteBuffer buffer = ByteBuffer.allocate(capacity);
        int length = -1;//-1代表读取完毕
        StringBuffer strBuffer = new StringBuffer("");
        while ((length = fchannel.read(buffer)) != -1){
            buffer.clear();
            strBuffer.append(new String(buffer.array(),0,length));
            if (0 == fin.available()){//读取到文档的最后，加上换行符
                strBuffer.append(endStr);
            }
            int endIndex = 0;
            while ((endIndex = strBuffer.indexOf(endStr)) != -1){
                String line = strBuffer.substring(0,endIndex);
                strBuffer.delete(0,endIndex+2);
                if (!line.startsWith("#")&&StringUtils.isNotBlank(line)){
                    setConfig(line);
                }
            }
        }
    }

    /**
     * 提取配置项及值
     * @param str
     */
    private void setConfig(String str){
        int index = str.indexOf("=");
        if (-1 != index){
            configMap.put(str.substring(0,index),str.substring(index+1));
        }else{
            throw new IllegalArgumentException("Non conformity [key=value] :"+str);
        }
    }

    private void setAllDB(){
        if (null == configMap || 0>=configMap.size()){
            throw new IllegalArgumentException("no Database config.");
        }
        String prefix = configMap.get(DBInfo.PREFIX);
        if (StringUtils.isNotBlank(prefix)){
            allDB.setPrefix(prefix.split(","));
        }
        DBInfo stdDBinfo = new DBInfo();
        stdDBinfo.setUrl(configMap.get(DBInfo.STD_URL));
        stdDBinfo.setUserName(configMap.get(DBInfo.STD_NAME));
        stdDBinfo.setPassword(configMap.get(DBInfo.STD_PASSWORD));
        stdDBinfo.setCatalog(configMap.get(DBInfo.STD_CATALOG));
        allDB.setStdDB(stdDBinfo);
        int index = 1;
        while (true){
            if (null==configMap.get(DBInfo.CON_URL+index)){
                break;
            }
            DBInfo conDBinfo = new DBInfo();
            conDBinfo.setUrl(configMap.get(DBInfo.CON_URL+index));
            conDBinfo.setUserName(configMap.get(DBInfo.CON_NAME+index));
            conDBinfo.setPassword(configMap.get(DBInfo.CON_PASSWORD+index));
            conDBinfo.setCatalog(configMap.get(DBInfo.CON_CATALOG+index));
            allDB.setContrastDB(conDBinfo);
            index ++;
        }
    }

    public AllDB getAllDB() {
        return allDB;
    }
}
